/*! \file mux.c
  \brief this file is the implementation of the multiplexer at the router
 
  The multiplexer assumes there are 4 streams, Youtube, Megavideo, 
  Zshare, and Netflix. It goes through the packets from these streams
  and merge them into one large array based on packet arrival times. In
  the end the large array has all the packets sorted by arrival time.
 
 */



#include "main.h"



/** @fn mux
 * @brief merges streams of packets into one
 * @callergraph
 *
 * @return total number of packets in the final array
 */
int mux(struct packet *M, struct packet *N, struct packet *Y, struct packet *Z, struct packet *packetArray)
{
  int totalNumberOfPackets=0; //!< as each packet is muxed, this is incremented
  
  int Nindx=0;
  int Mindx=0;
  int Zindx=0;
  int Yindx=0;
  
  Time tempYtime;
  Time tempZtime;
  Time tempMtime;
  Time tempNtime;
  
  
  while(totalNumberOfPackets < (MAX_NUM_MEGAVIDEO_USER_PACKETS + MAX_NUM_NETFLIX_USER_PACKETS + MAX_NUM_YOUTUBE_USER_PACKETS + MAX_NUM_ZSHARE_USER_PACKETS))
    {
      if (Yindx < MAX_NUM_YOUTUBE_USER_PACKETS)
  		tempYtime = Y[Yindx].internetDispatchTime; 
	  else 
	  		tempYtime.tv_usec = 1000000;
	  		
	  if (Zindx < MAX_NUM_ZSHARE_USER_PACKETS)
	  		tempZtime = Z[Zindx].internetDispatchTime;
	  else 
	  		tempZtime.tv_usec = 1000000;
	  		
	  if (Mindx < MAX_NUM_MEGAVIDEO_USER_PACKETS)
	  		tempMtime = M[Mindx].internetDispatchTime;
	  else 
	  		tempMtime.tv_usec = 1000000;
	  		
	  if (Nindx < MAX_NUM_NETFLIX_USER_PACKETS)
	  		tempNtime = N[Nindx].internetDispatchTime;
	  else 
  		tempNtime.tv_usec = 1000000;
  		
      // determine which one has arrived first, i.e. smallest time
      int smallestTime=0; // 0<-> Y
      Time temp=tempYtime;
      if( (int)(tempZtime.tv_usec) < (int)(temp.tv_usec) ) 
      {
			smallestTime=1; // 1<->Z
			temp = tempZtime;
      }
      if( (int)(tempMtime.tv_usec) < (int)(temp.tv_usec) ) 
      {
			smallestTime=2; // 2<->M
			temp = tempMtime;
      }
      if( (int)(tempNtime.tv_usec) < (int)(temp.tv_usec) ) 
      {
			smallestTime=3; // 3<->N
			temp = tempNtime;
      }
      
      // put the packet with smallest in the packet array
      if(smallestTime==0) { // a Y packet
	packetArray[totalNumberOfPackets]=Y[Yindx];
	Yindx++;
	tempYtime = Y[Yindx].internetDispatchTime;
      }
      else if(smallestTime==1) { // a Z packet 
	packetArray[totalNumberOfPackets]=Z[Zindx];
	Zindx++;
	tempZtime = Z[Zindx].internetDispatchTime;
      }
      else if(smallestTime==2) { // a M packet
	packetArray[totalNumberOfPackets]=M[Mindx];
	Mindx++;
	tempMtime = M[Mindx].internetDispatchTime;
      }
      else { // a N packet
	packetArray[totalNumberOfPackets]=N[Nindx];
	Nindx++;
	tempNtime = N[Nindx].internetDispatchTime;
      }
      totalNumberOfPackets++;      
    } 
  return totalNumberOfPackets;
}
  
